import dayjs from 'dayjs'
import {
	reportDate,
	shortcut2,
	shortcut3,
	shortcut4,
	shortcuts,
	shortcutsM,
	shortcutsMonth,
	shortcutsNoToday,
	shortcut3WithCurrPeriod,
	shortcut4WithCurrPeriod
} from '@/utils/consts'
import { mapGetters } from 'vuex'
import { Decimal } from 'decimal.js'
import { parseTime } from '@/utils'
import { Storage } from '@/utils/compose'
import { BUSINESS_MODELS } from '@/consts/map'

export default {
	components: { Copy: () => import('@/components/Copy/copy') },
	filters: {
		// 两位小数
		filterDecimals: function(val) {
			if (typeof val === 'number') {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 3) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				}
			} else {
				return '-'
			}
		},
		/**
		 * 有小数截取n位数显
		 * @param {*} val
		 * @param {*} n
		 * @returns
		 */
		filterDecimalsN: function(val, n) {
			if (typeof val === 'number') {
				return new Decimal(val).toFixed(n, Decimal.ROUND_DOWN)
			} else {
				return '-'
			}
		},
		// 四位小数
		filterDecimals4: function(val) {
			if (typeof val === 'number') {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 5) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 4,
						maximumFractionDigits: 4
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 4,
						maximumFractionDigits: 4
					})
				}
			} else {
				return '-'
			}
		},
		returnToZero: function(val) {
			if (typeof val === 'number') {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 3) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				}
			} else {
				return '0.00'
			}
		},
		returnLine: function(val) {
			if (typeof val === 'number') {
				return val
			} else {
				return '-'
			}
		},
		// 第一位和最后一位，中间用固定***代替
		parseStringToStar: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				return str.length > 2
					? str.substr(0, 1) +
							new Array(str.length - 2).join('*') +
							str.substr(-1)
					: str
			}
		},
		// * 中间2位使用*代替。两端数量不相等时，优先前端总长度小于等于2位时，显示 a*，只有1位也要显示a*
		parseStringMiddleToStar: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const len = str.length
				const middleIdx = Math.floor(len / 2)
				const isOdd = len % 2 === 1
				if (len > 2) {
					if (isOdd) {
						str =
							str.substr(0, middleIdx) +
							new Array(3).join('*') +
							str.substr(middleIdx + 2, len)
					} else {
						str =
							str.substr(0, middleIdx - 1) +
							new Array(3).join('*') +
							str.substr(middleIdx + 1, len)
					}
				} else {
					str = str.substr(0, 1) + '*'
				}
				return str
			}
		},
		// 区号不隐藏，若有区号区号和号码用空格隔开。号码隐藏中间4位，如总数为奇数，则前面-1，用*代替
		parseStringMiddlePhoneToStar: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const len = str.length
				const middleIdx = Math.floor(len / 2)
				const isOdd = len % 2 === 1
				if (isOdd) {
					str =
						str.substr(0, middleIdx - 2) +
						new Array(5).join('*') +
						str.substr(middleIdx + 2, len)
				} else {
					str =
						str.substr(0, middleIdx - 2) +
						new Array(5).join('*') +
						str.substr(middleIdx + 2, len)
				}

				return str
			}
		},
		// 邮箱字符大于等于3字符仅显示@前第一位和末位以及域名中间显示*，对于不足3字符的地址名，则仅显示@前第一位及域名
		parseEmailShowStar: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const arr = []
				if (str.indexOf('@') !== -1) {
					const strList = str.split('@')
					let newStr = ''
					if (strList[0] && strList[0].length >= 3) {
						newStr = strList[0].substring(1, strList[0].length - 1)
					} else {
						newStr = strList[0].substring(1, strList[0].length)
					}
					for (const item in [...newStr]) {
						arr[item] = [...newStr][item].replace(
							[...newStr][item],
							'*'
						)
					}
					const replaceStr = strList[0].replace(newStr, arr.join(''))
					str = `${replaceStr}@${strList[1]}`
					return str
				}
			}
		},
		// 真实姓名显示过滤
		parseRellyName: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const arr = []
				const nameEndStr = str.substr(str.length - 1, 1)
				const nameStr = str.substring(0, str.length - 1)
				for (const item in [...nameStr]) {
					arr[item] = [...nameStr][item].replace(
						[...nameStr][item],
						'*'
					)
				}
				const replaceStr = arr.join('')
				str = `${replaceStr}${nameEndStr}`
				return str
			}
		},
		// 身份证显示过滤
		parseIdCard: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const arr = []
				const nameStr = str.substring(3, str.length - 3)
				for (const item in [...nameStr]) {
					arr[item] = [...nameStr][item].replace(
						[...nameStr][item],
						'*'
					)
				}
				const replaceStr = arr.join('')
				str = str.replace(nameStr, replaceStr)
				return str
			}
		},
		// 银行卡显示过滤
		parseBankCard: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const arr = []
				const nameStr = str.substring(4, str.length - 3)
				for (const item in [...nameStr]) {
					arr[item] = [...nameStr][item].replace(
						[...nameStr][item],
						'*'
					)
				}
				const replaceStr = arr.join('')
				const firstStr = str.substring(0, 4)
				const secondStr = str.substring(str.length - 1, str.length - 4)
				str = `${firstStr}${replaceStr}${secondStr}`
				return str
			}
		},
		// 虚拟币显示过滤
		parseVirtualCurrency: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				// const arr = []
				// const nameStr = str.substring(4, str.length - 3)
				// for (const item in [...nameStr]) {
				// 	arr[item] = [...nameStr][item].replace(
				// 		[...nameStr][item],
				// 		'*'
				// 	)
				// }
				// const replaceStr = arr.join('')
				const replaceStr = '****'
				const firstStr = str.substring(0, 4)
				const secondStr = str.slice(-4)
				str = `${firstStr}${replaceStr}${secondStr}`
				return str
			}
		},
		// 商户key显示过滤
		parseMerchantKeyCard: function(str) {
			if (!str && str !== 0) {
				return '-'
			} else {
				const arr = []
				const nameStr = str.substring(2, str.length - 2)
				for (const item in [...nameStr]) {
					arr[item] = [...nameStr][item].replace(
						[...nameStr][item],
						'*'
					)
				}
				const replaceStr = arr.join('')
				str = str.replace(nameStr, replaceStr)
				return str
			}
		}
	},
	directives: {},
	data() {
		return {
			list: [],
			total: 0,
			loading: false,
			pageNum: 1,
			pageSize: 100,
			pageSizes: [10, 20, 50, 100, 200],
			layout: 'total, sizes, prev, pager, next, jumper',
			defaultTime: ['00:00:00', '23:59:59'],
			sortable: true,
			userName: '',
			indexDB: '',
			warehouseName: '',
			tableColumnData: {},
			dialogColumnData: {},
			dialogShowHide: false,
			pageCurrency: '',
			resetPassword: '',
			tableH: 480,
			currentDate: new Date().getDate()
		}
	},
	computed: {
		...mapGetters(['globalDics', 'merchantList', 'merchantInfo']),
		// 包含 今日、昨日、上周、本周、上月、本月、近一周（近7天）、最近一个月（近30天）、最近三个月（近90天）
		pickerShortcut2() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcut2
			}
		},
		// 包含 今日、昨日、上周、本周、上月、本月、近一周（近7天）、最近一个月（近30天）
		pickerShortcut3() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcut3
			}
		},
		// 包含 今日、昨日、上周、本周、上月、本月、近一周（近7天）、最近一个月（近30天）
		pickerShortcut4() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate }) {
					if (!maxDate) {
						_this.maxDate = maxDate
					}
				},
				shortcuts: shortcut4
			}
		},
		// 包含 本账期、今日、昨日、上周、本周、上月、本月、近一周（近7天）、最近一个月（近30天）
		pickerShortcutWithCurrPeriod() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcut3WithCurrPeriod
			}
		},
		pickerShortcutWithCurrTowPeriod() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcut4WithCurrPeriod
			}
		},
		pickerOptions() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcuts
			}
		},
		pickerOptions1() {
			const _this = this
			return {
				// disabledDate(time) {
				// 	const now = dayjs()
				// 		.endOf('day')
				// 		.valueOf()
				// 	return time.getTime() > now
				// },
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcuts
			}
		},
		pickerOptionsReport() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: reportDate
			}
		},
		pickerOptionsM() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcutsM
			}
		},
		pickerOptionsNoToday() {
			const _this = this
			return {
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcutsNoToday
			}
		},
		// 本月,上月,近三个月,近六个月
		pickerOptionsMonth() {
			const _this = this
			return {
				disabledDate(time) {
					const now = dayjs()
						.endOf('day')
						.valueOf()
					return time.getTime() > now
				},
				onPick({ maxDate, minDate }) {
					if (!maxDate) {
						_this.minDate = minDate
					}
				},
				shortcuts: shortcutsMonth
			}
		},
		checkOrderParams() {
			const SortLine = new Map([
				['createDt', 'createDt'],
				['auditTime', 'auditTime'],
				['applyTime', 'applyTime'],
				['gameId', 'gameId'],
				['createdAt', 'createdAt'],
				['updatedAt', 'updatedAt'],
				['loginTime', 'loginTime'],
				['withdrawalTime', 'withdrawalTime'],
				['modifyDt', 'modifyDt']
			])
			return SortLine
		},
		pageParams() {
			return {
				pageNum: this.pageNum,
				pageSize: this.pageSize
			}
		},
		// 校验中文占两个字符，英文和数字占一个字符
		nickNameRule(val) {
			const inputKey = Object.keys(val.queryData)
			const inputVal = Object.values(val.queryData)
			const split = inputVal[0].split('')
			// 计算已输入的长度
			const map = split.map((s, i) =>
				val.queryData[inputKey].charCodeAt(i) >= 0 &&
				val.queryData[inputKey].charCodeAt(i) <= 128
					? 1
					: 2
			)
			// 这里设置想要限制的长度
			const maxLength = 12
			let n = 0
			const charLength =
				map.length > 0 &&
				map.reduce((accumulator, currentValue, index) => {
					if (
						accumulator === maxLength ||
						accumulator === maxLength - 1
					) {
						n = index
					}
					return accumulator + currentValue
				})
			if (charLength > maxLength) {
				val.queryData[inputKey] = split.slice(0, n).join('')
			}
		}
	},
	created() {
		this.userName = localStorage.getItem('username')
	},
	mounted() {
		const option = this.$options.doNotInit
		if (!option) {
			this.initList()
		}
	},
	activated() {
		const nowDate = new Date().getDate()
		if (this.currentDate !== nowDate) {
			this.currentDate = nowDate
			this.reset()
		}
	},
	watch: {
		total: {
			handler(newVal, oldVal) {
				if (!newVal) {
					return (this.pageNum = 1)
				} else if (
					newVal < oldVal &&
					Math.ceil(newVal / this.pageSize) !== this.pageNum
				) {
					this.pageNum =
						(oldVal - 1) % this.pageSize === 0 && this.pageNum > 1
							? this.pageNum - 1
							: this.pageNum
					// this.loadData()
				}
			},
			deep: true
		}
	},
	methods: {
		// 真实姓名显示过滤
		parseRellyName: function(str) {
			if ((!str && str !== 0) || str == '-') {
				return '-'
			} else {
				const arr = []
				const nameStartStr = str.substr(0, 1)
				const nameEndStr = str.substr(str.length - 1, 1)
				const nameStr = str.substring(1, str.length - 1)
				for (const item in [...nameStr]) {
					arr[item] = [...nameStr][item].replace(
						[...nameStr][item],
						'*'
					)
				}
				const replaceStr = arr.join('')
				str = replaceStr
					? `${nameStartStr}${replaceStr}${nameEndStr}`
					: `${nameStartStr}*`
				return str
			}
		},
		// 区号不隐藏，若有区号区号和号码用空格隔开。号码隐藏中间4位，如总数为奇数，则前面-1，用*代替
		parseStringMiddlePhoneToStar: function(str) {
			if ((!str && str !== 0) || str == '-') {
				return '-'
			} else {
				const len = str.length
				const middleIdx = Math.floor(len / 2)
				const isOdd = len % 2 === 1
				if (isOdd) {
					str =
						str.substr(0, middleIdx - 3) +
						new Array(5).join('*') +
						str.substr(middleIdx + 4, len)
				} else {
					str =
						str.substr(0, middleIdx - 3) +
						new Array(5).join('*') +
						str.substr(middleIdx + 4, len)
				}

				return str
			}
		},
		mappingBusinessModel(key) {
			return BUSINESS_MODELS.find((item) => item?.value == key)?.label
		},
		getTypeName(code, typeArr) {
			if (!code && Number(code) !== 0) return '-'
			if (Array.isArray(typeArr)) {
				return (
					typeArr.find((item) =>
						!isNaN(Number(code))
							? Number(item.code) === Number(code)
							: item.code === code
					)?.description || '-'
				)
			} else {
				return '-'
			}
		},
		getFormateDate(date, type = 'ymd') {
			let format = 'YYYY-MM-DD'
			if (type === 'ym') {
				format = 'YYYY-MM'
			}
			return date ? dayjs(String(date)).format(format) : '-'
		},
		getSaveTableData() {
			const getLocalTableData = Storage.get('commonTableKey')
			if (
				getLocalTableData &&
				Object.keys(getLocalTableData).length > 0
			) {
				const getUserKey = Object.keys(getLocalTableData)
				const splitKey = getUserKey[0]?.split('_')
				if (`${this.$store.state.user.userInfo?.id}` === splitKey[0]) {
					return getLocalTableData
				}
			}
		},
		getRowClass({ row, column, rowIndex, columnIndex }) {
			if (rowIndex === 0) {
				return 'background:#EFEFEF'
			} else {
				return ''
			}
		},
		typeFilter(code, name, customDicsArr) {
			if (!code && code !== 0) return '-'

			const dicsArr =
				customDicsArr && Array.isArray(customDicsArr)
					? customDicsArr
					: this.globalDics[name]
			return (
				dicsArr?.find((item) =>
					!isNaN(Number(code))
						? Number(item.code) === Number(code)
						: item.code === code
				)?.description || '-'
			)
		},
		typeListFilter(code, name) {
			const textList = []
			const listCode = code?.split(',')
			if (!listCode || listCode.length === 0) return '-'
			listCode.map((item) => {
				switch (item) {
					case '1':
						textList.push(this.globalDics[name][0].description)
						break
					case '3':
						textList.push(this.globalDics[name][1].description)
						break
					case '5':
						textList.push(this.globalDics[name][2].description)
						break
					case '6':
						textList.push(this.globalDics[name][3].description)
						break
				}
			})
			return textList.toString()
		},
		merchantFilter(id) {
			return String(id) === '0'
				? this.$t('common.super')
				: this.merchantList.find((item) => item.id === id)
						?.merchantName || '-'
		},
		getParams(params) {
			if (typeof params === 'object' && params) {
				Object.keys(params).forEach((key) => {
					if (params[key] === '') {
						params[key] = undefined
					}
				})
			}
			return Object.assign({}, params, {
				pageNum: this.pageNum,
				pageSize: this.pageSize
			})
		},
		initList() {
			this.pageNum = 1
			this.list = []
			this.loadData()
		},
		loadData() {
			// 每个列表自己的获取数据的方法需要重写
		},
		// 改变列表条数
		handleSizeChange(value) {
			this.pageNum = 1
			this.pageSize = value
			this.loadData()
		},
		handleCurrentChange(value) {
			this.pageNum = value
			this.loadData()
		},
		enterSearch(e) {
			const event = e || window.event
			const key = event.which || event.keyCode || event.charCode
			if (key === 13) {
				this.pageNum = 1
				this.loadData()
			}
		},
		search() {
			this.pageNum = 1
			this.loadData()
		},
		reset() {},
		copy(e) {
			if (e) {
				this.$copyText(e).then(() => {
					this.$message({
						type: 'success',
						message: this.$t('common.copy')
					})
				})
			}
		},
		changeTableSort({ column, prop, order }) {
			this.pageNum = 1
			this.queryData.orderProperties = prop
			const orderParams = this.checkOrderParams.get(prop)
			if (orderParams) {
				if (order === 'ascending') {
					// 升序
					this.queryData.orderType = 'asc'
				} else if (column.order === 'descending') {
					// 降序
					this.queryData.orderType = 'desc'
				} else {
					delete this.queryData.orderKey
					delete this.queryData.orderType
					delete this.queryData.orderProperties
				}
				this.loadData()
			}
		},
		filterChange(filters) {
			if (filters.type) {
				this.listQuery.type = filters.type[0]
			}
			this.loadData()
		},
		throttle(func, delay = 60) {
			let timer = null
			let start = 0
			return function(...args) {
				const current = +new Date()
				clearTimeout(timer)
				if (current - start >= delay) {
					func.apply(this, args)
					start = current
				} else {
					timer = setTimeout(() => func.apply(this, args), delay)
				}
			}
		},
		disabledDelay(property, bool, delay = 1000) {
			setTimeout(() => {
				this[property] = bool
			}, delay)
		},
		decimalToFixed(val) {
			if (typeof val === 'number' && val !== 0) {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 3) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				}
			} else if (val === 0) {
				return 0
			} else {
				return '-'
			}
		},
		decimalToDiv(val, y) {
			return val * 1 === 0 ? 0 : new Decimal(val).div(y || 100)
		},
		decimalToMul(val) {
			return val * 1 === 0 ? 0 : new Decimal(val).mul(100)
		},
		getValue(val) {
			return val || val === 0 ? val : '-'
		},
		getNumberValue(val) {
			return val || val === 0 ? val : '-'
		},
		decimalToFixed2(val) {
			if (typeof val === 'number') {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 3) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				}
			} else {
				return '-'
			}
		},
		decimalToMul2(val, y) {
			return val || val === 0 ? new Decimal(val).mul(y || 100) : '-'
		},
		getSerialNum(index) {
			return (this.pageNum - 1) * this.pageSize + index + 1
		},
		getParentSerialNum({ index, pageNum, pageSize }) {
			return (pageNum - 1) * pageSize + index + 1
		},
		// 两位小数
		filterSummar: function(val) {
			if (typeof val === 'number') {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 3) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 2,
						maximumFractionDigits: 2
					})
				}
			} else {
				return ''
			}
		},
		// 四位小数
		filterSummar4: function(val) {
			if (typeof val === 'number') {
				const toStr = val.toString()
				const str = toStr.indexOf('.')
				if (str !== -1) {
					return (
						toStr.substring(0, toStr.indexOf('.') + 5) - 0
					).toLocaleString('en-us', {
						minimumFractionDigits: 4,
						maximumFractionDigits: 4
					})
				} else {
					return val.toLocaleString('en-us', {
						minimumFractionDigits: 4,
						maximumFractionDigits: 4
					})
				}
			} else {
				return ''
			}
		},
		/**
		 * 处理小数和千分位
		 * @param sign 传入货币
		 * @param num 传入金额
		 * @param digit  保留小数位数  默认两位
		 * @param flag  是否显示千分位  默认保留千分位
		 * @returns
		 */
		handleNumber(sign, num, digit = 2, flag = true, plusSign = false) {
			if (typeof num === 'number' || typeof num === 'string') {
				let currencySymbol = Storage.get('currencySymbol')
				num = parseFloat(num) ? num : 0
				if (sign === '¥') {
					currencySymbol = sign
				}
				if (sign !== '') {
					switch (currencySymbol) {
						case '¥':
							digit = 2
							break
						case '$':
							digit = 2
							break
						case '฿':
							digit = 2
							break
						case '₫':
							digit = 0
							break
						default:
							digit = 2
					}
					const data = new Decimal(
						new Decimal(num).toFixed(digit, Decimal.ROUND_DOWN)
					).toNumber()
					const newData = data.toLocaleString('en-us', {
						minimumFractionDigits: data === 0 ? 0 : digit,
						useGrouping: flag
					})
					const regexp = /(?:\.0*|(\.\d+?)0+)$/
					if (newData.indexOf('-') !== -1) {
						const str1 = newData.replace(/\-/g, '')
						return `${
							data === 0 ? '' : '-'
						}${currencySymbol}${str1.replace(regexp, '$1')}`
					} else {
						return `${
							plusSign && data !== 0 ? '+' : ''
						}${currencySymbol}${newData.replace(regexp, '$1')}`
					}
				} else {
					const data = new Decimal(
						new Decimal(num).toFixed(digit, Decimal.ROUND_DOWN)
					).toNumber()
					const newData = data.toLocaleString('en-us', {
						minimumFractionDigits: data === 0 ? 0 : digit,
						useGrouping: flag
					})
					return newData
				}
			} else if (num === null) {
				return '-'
			} else {
				if (sign !== '') {
					return '$0'
				} else {
					return '-'
				}
			}
		},
		currencyTo10k(n) {
			return new Decimal(n / 10000).toFixed(2, Decimal.ROUND_DOWN)
		},
		/**
		 * 处理小数和千分位
		 * @param sign 传入货币
		 * @param num 传入金额
		 * @param digit  保留小数位数  默认两位
		 * @param flag  是否显示千分位  默认保留千分位
		 * @returns
		 */
		handleTotalNumber(sign, num, digit = 0, flag = true, plusSign = false) {
			const currencySymbol = Storage.get('currencySymbol')
			if (typeof num === 'number' || typeof num === 'string') {
				switch (currencySymbol) {
					case '￥':
						digit = 2
						break
					case '฿':
						digit = 2
						break
					case '₫':
						digit = 0
						break
					case '$':
						digit = 2
						break
					default:
						digit = 2
				}
				num = parseFloat(num) ? num : 0
				if (sign === '10k') num /= 10000
				const data = new Decimal(
					new Decimal(num).toFixed(digit, Decimal.ROUND_DOWN)
				).toNumber()
				const str = data.toLocaleString('en-us', {
					minimumFractionDigits: data === 0 ? 0 : digit,
					useGrouping: flag
				})
				const regexp = /(?:\.0*|(\.\d+?)0+)$/
				if (str.indexOf('-') !== -1) {
					const str1 = str.replace(/\-/g, '')
					return `${
						data === 0 ? '' : '-'
					}${currencySymbol}${str1.replace(regexp, '$1')}`
				} else {
					return `${
						plusSign && data !== 0 ? '+' : ''
					}${currencySymbol}${str.replace(regexp, '$1')}`
				}
			} else if (num === null) {
				return '-'
			} else {
				return `${currencySymbol}0`
			}
		},
		// 处理金额相关的字体颜色
		handleNumberColor(val) {
			let color = ''
			if (val > 0) {
				color = 'color:#4B7902' // 绿色
			}
			if (val < 0) {
				color = 'color:#D9001B' // 红色
			}
			return color
		},
		// 币种符号,默认为$
		handleCurrency(sign, flag) {
			const currencySymbol = Storage.get('currencySymbol')
			if (flag) {
				return currencySymbol
			} else {
				return ''
			}
		},
		handlePercentage(num, flag = true) {
			if (!num) {
				return '0%'
			}
			const data = new Decimal(
				new Decimal(num).toFixed(3, Decimal.ROUND_DOWN)
			).toNumber()
			const str = data.toLocaleString('en-us', {
				minimumFractionDigits: data === 0 ? 0 : 3,
				useGrouping: flag
			})
			const regexp = /(?:\.0*|(\.\d+?)0+)$/
			if (str || str === 0) {
				return `${str.replace(regexp, '$1')}%`
			} else {
				return `-`
			}
		},
		// 时间转换
		parseTime(time, cFormat) {
			if (!time) return '-'
			return parseTime(time, cFormat)
		},
		/** 比较前后两个值
		 * @param obj   form表单字段
		 * @param flag  点击的输入框标识
		 * @param minField   点击的输入框字段名
		 * @param maxField   需要进行比较的字段名
		 * @param msg   提示语
		 */
		handleAmount(obj, flag, minField, maxField, msg) {
			if (obj[minField] && obj[maxField]) {
				switch (flag) {
					case 1:
						if (Number(obj[minField]) > Number(obj[maxField])) {
							obj[minField] = undefined
							this.$message.warning(msg)
						}
						break
					case 2:
						if (Number(obj[maxField]) < Number(obj[minField])) {
							obj[maxField] = undefined
							this.$message.warning(msg)
						}
						break
				}
			}
		},
		/**
		 * @param  len  需要生成的随机数长度
		 */
		// 生成随机密码
		setRandomPwd(len) {
			// 验证0-9的任意数字最少出现1次。
			const regNumber = /\d+/
			// 验证大小写26个字母任意字母最少出现1次。
			const regLetter = /[a-zA-Z]+/
			// 字母
			const letterStr =
				'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
			// 数字加字母
			const letterNumStr =
				'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
			// 随机生成首位，且必须是字母
			const firstNum = Math.floor(Math.random() * (letterStr.length - 1))
			const letterVal = letterStr[firstNum]
			// 随机生成值
			let value = ''
			for (let i = 0; i < len - 1; i++) {
				const randomVal = Math.round(
					Math.random() * (letterNumStr.length - 1)
				)
				value += letterNumStr[randomVal]
			}
			// 最终值
			const text = letterVal + value
			// 判断如果只有字母则从新生成一次
			if (regNumber.test(text) && regLetter.test(text)) {
				this.resetPassword = text
			} else {
				this.setRandomPwd(len)
			}
		},
		setRandomPassword(length) {
			var lowercase = 'abcdefghijklmnopqrstuvwxyz'
			var uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
			var numbers = '0123456789'
			var specialChars = '!@#$%^&*()_+{}:"<>?[];\',./`~'

			var passwordChars = [
				lowercase.charAt(Math.floor(Math.random() * lowercase.length)),
				uppercase.charAt(Math.floor(Math.random() * uppercase.length)),
				numbers.charAt(Math.floor(Math.random() * numbers.length)),
				specialChars.charAt(
					Math.floor(Math.random() * specialChars.length)
				)
			]

			var charset = lowercase + uppercase + numbers + specialChars
			for (var i = 4; i < length; i++) {
				passwordChars.push(
					charset.charAt(Math.floor(Math.random() * charset.length))
				)
			}

			// 打乱数组顺序
			passwordChars.sort(function() {
				return 0.5 - Math.random()
			})

			this.resetPassword = passwordChars.join('')
		},
		// 创建数据库
		initIndexDB(warehouseName, data) {
			this.warehouseName = warehouseName
			const request = indexedDB.open(warehouseName)
			request.onupgradeneeded = (event) => {
				const db = event.target.result
				db.createObjectStore(warehouseName, {
					keyPath: 'id',
					autoIncrement: true
				})
			}
			request.onsuccess = (event) => {
				this.indexDB = event.target.result
				this.addIndexDB(data)
				this.getIndexDB(data)
			}
		},
		// 添加数据库数据
		addIndexDB(data) {
			const request = this.indexDB
				.transaction([this.warehouseName], 'readwrite')
				.objectStore(this.warehouseName)
				.add({
					id: this.userName,
					obj: data
				})
			request.onsuccess = (event) => {
				this.getIndexDB(data)
			}
		},
		// 获取数据库数据
		getIndexDB(data) {
			this.dialogColumnData = {}
			const transaction = this.indexDB.transaction([this.warehouseName])
			const objectStore = transaction.objectStore(this.warehouseName)
			const list = []
			objectStore.openCursor().onsuccess = (event) => {
				const cursor = event.target.result
				if (cursor) {
					list.push(cursor.value)
					cursor.continue()
				} else {
					for (let i = 0; i < list.length; i++) {
						const ele = list[i]
						if (ele.id === this.userName) {
							const dbObj = {}
							for (const j in data) {
								if (j in ele.obj) {
									dbObj[j] = ele.obj[j]
								} else {
									dbObj[j] = data[j]
								}
							}
							this.tableColumnData = { ...dbObj }
							this.dialogColumnData = { ...dbObj }
						}
					}
				}
			}
		},
		// 更新数据库
		updateIndexDB() {
			const request = this.indexDB
				.transaction([this.warehouseName], 'readwrite')
				.objectStore(this.warehouseName)
				.put({
					id: this.userName,
					obj: this.dialogColumnData
				})
			request.onsuccess = (event) => {
				this.dialogShowHide = false
				this.getIndexDB(this.tableColumnData)
			}
			request.onerror = (event) => {}
		},
		// 数字类型颜色过滤 正数 绿色;  负数 红色
		getNumberValColor(val) {
			val = Number(val)
			let className = ''
			if (val > 0) {
				className = 'enableColor'
			} else if (val < 0) {
				className = 'redColor'
			}
			return className
		},
		getWidth(value, scale = 1.25) {
			if (typeof value === 'object' && value) {
				return value[this.$i18n.locale]
			}
			if (this.$i18n.locale === 'zh_CN') {
				return value
			}
			if (typeof value !== 'object' && value) {
				const number = String(value).match(/\d+/)
				return typeof value === 'number'
					? +String(value).replace(/\d+/, number * scale)
					: String(value).replace(/\d+/, number * scale)
			}
		},
		getKey(key, item = 2) {
			const map = {
				zh_CN: 'zh',
				en_US: 'en',
				vi_VN: 'vn',
				th_TH: 'th'
			}
			let name = map[this.$i18n.locale]
			if (typeof item === 'object') {
				name = item.map ? item.map[this.$i18n.locale] : name
			}
			const keys = [
				`${name}${key.charAt(0).toUpperCase()}${key.slice(1)}`,
				`${key}${name.charAt(0).toUpperCase()}${name.slice(1)}`
			]
			if (/[A-Z]/.test(key)) {
				const match = key.match(/[A-Z]/g)
				if (Array.isArray(match)) {
					const array = match.map(
						(item) =>
							`${key.slice(0, key.indexOf(item))}${name
								.charAt(0)
								.toUpperCase()}${name.slice(1)}${key.slice(
								key.indexOf(item)
							)}`
					)
					keys.push(...array)
				}
			}
			if (
				this.$i18n.locale === 'zh_CN' &&
				(typeof item === 'number' || !item.zh)
			) {
				return key
			} else {
				if (typeof item === 'number') {
					return keys[2]
				} else if (typeof item === 'object') {
					return keys[item.index !== undefined ? item.index : 2]
				}
			}
		},
		exportExcelConfirm({
			message = this.$t('common.is_export'),
			info = this.$t('common.excess_data'),
			title = this.$t('common.success_tip'),
			type = 'warning',
			confirmButtonText = this.$t('common.confirm'),
			cancelButtonText = this.$t('common.cancel')
		} = {}) {
			return this.$confirm(
				`<strong>${message}</strong></br><span style='font-size:12px;color:#c1c1c1'>${info}</span>`,
				title,
				{
					dangerouslyUseHTMLString: true,
					confirmButtonText,
					cancelButtonText,
					type
				}
			)
		},
		exportExcelPublic({
			api,
			params = {},
			confirmButtonText,
			cancelButtonText,
			title,
			info,
			message,
			type
		}) {
			if (params) {
				delete params.orderKey
				delete params.orderType
			}
			if (!api) {
				this.$message({
					type: 'info',
					message: this.$t('common.empty_api_info'),
					duration: 1500
				})
				return false
			}
			return new Promise((resolve, reject) => {
				this.exportExcelConfirm({
					confirmButtonText,
					cancelButtonText,
					title,
					info,
					message,
					type
				})
					.then(() => {
						this.$api[api](params)
							.then((res) => {
								const { data, status } = res
								if (res && status === 200) {
									const { type } = data
									if (
										type &&
										type.includes('application/json')
									) {
										const reader = new FileReader()
										reader.onload = (evt) => {
											if (evt.target.readyState === 2) {
												const {
													target: { result }
												} = evt
												const ret = JSON.parse(result)
												if (ret.code !== 200) {
													this.$message({
														type: 'error',
														message: ret.msg,
														duration: 1500
													})
												}
												this.$message({
													type: 'success',
													message: this.$t(
														'common.export_success'
													),
													duration: 1500
												})
											}
										}
										reader.readAsText(data)
									} else {
										if (!res.data.code) {
											const result = res.data
											const disposition =
												res.headers[
													'content-disposition'
												]
											const fileNames =
												disposition &&
												disposition.split("''")
											let fileName =
												Array.isArray(fileNames) &&
												fileNames.length &&
												fileNames[1]
											fileName = decodeURIComponent(
												fileName
											)
											const blob = new Blob([result], {
												type: 'application/octet-stream'
											})
											if (
												'download' in
												document.createElement('a')
											) {
												const downloadLink = document.createElement(
													'a'
												)
												downloadLink.download =
													fileName || ''
												downloadLink.style.display =
													'none'
												downloadLink.href = URL.createObjectURL(
													blob
												)
												document.body.appendChild(
													downloadLink
												)
												downloadLink.click()
												URL.revokeObjectURL(
													downloadLink.href
												)
												document.body.removeChild(
													downloadLink
												)
											} else {
												window.navigator.msSaveBlob(
													blob,
													fileName
												)
											}
											this.$message({
												type: 'success',
												message: this.$t(
													'common.export_success'
												),
												duration: 1500
											})
											return resolve(result)
										} else {
											this.$message.error(res.data.msg)
											return reject(res.data)
										}
									}
								} else if (data.taskId) {
									this.$message({
										type: 'success',
										message:
											'后台导出中，请在我的下载中查看进度',
										duration: 1500
									})
									this.$store.commit(
										'user/SET_MYDOWNLOADBADGE',
										1
									)
									return resolve(data)
								}
							})
							.catch((e) => {
								console.error(e)
								return reject(e)
							})
					})
					.catch((e) => {
						this.$message({
							type: 'info',
							message: this.$t('common.canceled')
						})
						return reject(e)
					})
			})
		}
	}
}
